#ifndef __DALELIB_SKELETON_H__
#define __DALELIB_SKELETON_H__


#include <map>
#include <vector>
using namespace std;

#include <dalelib/maths/m4.h>
#include <dalelib/graveyard/bone.h>

namespace dalelib
{


class Skeleton
{
public:

	struct MarionetteString
	{
		string _bone_name;
		string _bone_target_name;
		float _speed;
		MarionetteString(const string _Name,const string _TargetName,const float _Speed)
			: _bone_name(_Name)
			, _bone_target_name(_TargetName)
			, _speed(_Speed)
		{  }
	};

	vector<MarionetteString> _strings;


	typedef vector<Bone*> BoneList;
	typedef map<string,Bone*> BoneMap;

protected:

	struct TempBoneStruct { string name; v3 start,end; string parent_name; int parent_index; v3 amin, amax; };

	BoneList _bone_list;
	BoneMap _bone_map;

	vector<m4> _transforms; // just a linear array of bone transforms for passing to shader

public:

	virtual ~Skeleton();

	int getNumBones() { return _bone_list.size(); }
	BoneList& getBoneList() { return _bone_list; }
	BoneMap& getBoneMap() { return _bone_map; }
	Bone* getBone(const int _Index) { return _bone_list[_Index]; }
	Bone* getBone(const string _Name) { return _bone_map[_Name]; }
	m4* getTransformArray() { return &_transforms[0]; }

	void init();
	void update();
	void draw(const int _CurrentBone=-1);
	void load(const string _FileName);
	void loadMarionetteStrings(const string _FileName);
	void scale(const v3 _Scale);
	void translate(const v3 _Vec);
	void setGlobalMatRestInv();
	void inverseKinematicPull(const string _BoneName,v3 _Target,const float _Speed,const int _MaxNumLinks=100);
};

} // namespace dalelib

#endif
